package com.github.easyms.server.service.auth.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.easyms.common.constant.AuthConstants;
import com.github.easyms.common.constant.EasymsServiceStatus;
import com.github.easyms.common.constant.GlobalConstants;
import com.github.easyms.common.entity.auth.Menu;
import com.github.easyms.common.entity.auth.Role;
import com.github.easyms.common.entity.auth.User;
import com.github.easyms.common.exception.EasymsException;
import com.github.easyms.common.util.StringHelper;
import com.github.easyms.common.vo.EasymsPage;
import com.github.easyms.server.mapper.auth.RoleMapper;
import com.github.easyms.server.service.auth.MenuService;
import com.github.easyms.server.service.auth.RoleMenuService;
import com.github.easyms.server.service.auth.RoleService;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.apache.shiro.SecurityUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 角色业务
 *
 * @author Leo.Liao
 * @date 2020-05-02 02:35:26
 */
@Service("roleService")
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

    @Resource
    private RoleMapper roleMapper;

    @Resource
    private MenuService menuService;

    @Resource
    private RoleMenuService roleMenuService;

    @Override
    public <E extends IPage<Role>> E page(E page) {
        EasymsPage<Role> easymsPage = (EasymsPage<Role>) page;
        Role condition = easymsPage.getCondition();
        EasymsPage<Role> roleEasymsPage = roleMapper.selectRolePage(easymsPage, condition);
        return (E)roleEasymsPage;
    }

    @Override
    public boolean save(Role entity) {
        entity.setCreateTime(LocalDateTime.now());
        // 创建角色数据
        roleMapper.insert(entity);
        // 创建授权菜单关联数据
        roleMenuService.updateRoleMenus(entity.getRoleId(),buildAccessList(entity.getAccessList()),entity.getEditUser());
        return true;
    }

    @Override
    public boolean removeById(Serializable id) {
        Role role = (Role) id;
        roleMenuService.deleteByRoleId(role.getRoleId());
        return super.removeById(id);
    }

    @Override
    public boolean updateById(Role entity) {
        entity.setUpdateTime(LocalDateTime.now());
        // 创建角色数据
        roleMapper.updateById(entity);
        // 创建授权菜单关联数据
        roleMenuService.updateRoleMenus(entity.getRoleId(),buildAccessList(entity.getAccessList()),entity.getEditUser());
        return true;
    }

    @Override
    public Role selectByRoleName(String roleName) {
        Role role = roleMapper.selectOne(Wrappers.<Role>lambdaQuery()
                .eq(Role::getRoleName, roleName)
                .last("limit 1")
        );
        return role;
    }

    @Override
    public List<Role> listCombobox(Role entity,String q) {
        return roleMapper.selectList(Wrappers.<Role>lambdaQuery()
                .like(!StringHelper.isEmpty(q),Role::getRoleName, q)
                .eq(Role::getStatus, GlobalConstants.DataStatus.ACTIVE)
                .last("limit 20")
        );
    }

    /**
     * 构建符合要求的菜单数据
     * @param accessList
     * @return
     */
    private List<String> buildAccessList(List<String> accessList){
        // 获取传入的菜单IDs，遍历检查，如果是二级菜单则检查传入的IDs中是否存在其上级菜单的ID，不存在则加入
        List<String> saveAccessList = Lists.newArrayList(accessList);
        for(String menuId:accessList){
            Menu tempMenu = menuService.getById(menuId);
            // 检查菜单ID有效性
            if(tempMenu == null){
                throw new EasymsException(EasymsServiceStatus.INVALID_PARAM);
            }
            if(AuthConstants.MenuType.CHILD.equals(tempMenu.getMenuType())){
                // 不包含则加入
                if(!saveAccessList.contains(tempMenu.getPmenuId())){
                    saveAccessList.add(tempMenu.getPmenuId());
                }
            }
        }
        // 去除重复值
        saveAccessList = Lists.newArrayList(Sets.newHashSet(saveAccessList));
        return saveAccessList;
    }

}
